/**
 * 
 * @param {Function} fn 
 * @param {number} delay 
 * @returns void
 */
const debounce = (fn, delay) => {
  let timer = null
  return function (...args) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn.apply(this, args)
      clearTimeout(timer)
    }, delay)
  }
}

/**
 * 
 * @param {Function} fn 
 * @param {number} delay 
 * @returns {Function}
 */
const throttle = (fn, delay) => {
  let canRun = true
  return function (...args) {
    if (!canRun) return
    canRun = false
    setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

const mockFetch = (id) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(id)
    }, 3000)
  })
}

const myDebouncFn = debounce(mockFetch, 2000)
myDebouncFn(1)
myDebouncFn(2)
myDebouncFn(3)
myDebouncFn(4)